﻿using Authority.DataTransferObject.MenuAuthority;
using Authority.Doamin;
using Authority.Doamin.IRepository;
using Authority.Doamin.View;
using Authority.EFRepositoryImpl;
using Authority.IServices;
using Authority.IServices.Model.Menu;
using AutoMapper;
using HelperFromTheSkeleton.Convert;
using HelperFromTheSkeleton.ExtendMethod;

namespace Authority.ServiceImpl
{
    /// <summary>
    /// 菜单权限服务
    /// </summary>
    public class MenuAuthorityServiceImpl : IMenuAuthorityService
    {
        private readonly IMenuAuthorityRepository _menuAuthorityRepository;
        private readonly IRoleAuthorityMenuRepository _roleMenuRepository;
        private readonly ISubsystemRepository _subsystemRepository;
        private readonly IUnitWork _unitWork;
        private readonly IMapper _mapper;

        public MenuAuthorityServiceImpl(IUnitWork unitWork,
            IMapper mapper,
            IMenuAuthorityRepository menuAuthorityRepository,
            ISubsystemRepository subsystemRepository,
            IRoleAuthorityMenuRepository roleAuthorityMenuRepository
            )
        {
            _menuAuthorityRepository = menuAuthorityRepository;
            _unitWork = unitWork;
            _mapper = mapper;
            _roleMenuRepository = roleAuthorityMenuRepository;
            _subsystemRepository = subsystemRepository;
        }

        /// <summary>
        /// 新增菜单权限
        /// </summary>
        /// <param name="model"></param>
        /// <exception cref="InvalidOperationException"></exception>
        public async Task AddAsync(AddMenuModel model)
        {
            if (string.IsNullOrEmpty(model.Code)) throw new InvalidOperationException("菜单Code不能为空");
            if (string.IsNullOrWhiteSpace(model.Name)) throw new InvalidOperationException("菜单名称不能为空");
            if (model.SubsystemID == Guid.Empty) throw new InvalidOperationException("子系统ID不能为空");
            if (await _subsystemRepository.CountAsync(m => m.ID == model.SubsystemID) <= 0) throw new InvalidOperationException("无效的子系统");
            if (await _menuAuthorityRepository.CountAsync(m => (m.Name == model.Name || m.Code == model.Code) && m.SubsystemID == model.SubsystemID) > 0) throw new InvalidOperationException("子系统内的菜单名称、编号不允许重复");
            MenuAuthority dbInfo = new();
            model.CopyProperty(dbInfo);
            _unitWork.Add(dbInfo);
            await _unitWork.CommitAsync();
        }

        /// <summary>
        /// 修改菜单权限
        /// </summary>
        /// <param name="model"></param>
        /// <exception cref="InvalidOperationException"></exception>
        public async Task EditAsync(EditMenuModel model)
        {
            if (string.IsNullOrEmpty(model.Code)) throw new InvalidOperationException("菜单Code不能为空");
            if (string.IsNullOrWhiteSpace(model.Name)) throw new InvalidOperationException("菜单名称不能为空");
            if (model.ID == Guid.Empty) throw new InvalidOperationException("ID不能为空");
            MenuAuthority dbInfo = await _menuAuthorityRepository.FirstAsync(m => m.ID == model.ID) ?? throw new InvalidOperationException("找不到此菜单权限");
            if (await _menuAuthorityRepository.CountAsync(m => (m.Name == model.Name || m.Code == model.Code) && m.SubsystemID == dbInfo.SubsystemID && m.ID != model.ID) > 0) throw new InvalidOperationException("子系统内的菜单名称、编号不允许重复");
            var subset = await _menuAuthorityRepository.GetAllSubsetAsync(model.ID);
            if (subset?.Count(m => m.ID == model.ParentID) > 0) throw new InvalidOperationException("设置的父级不能再自己的子集中");
            model.CopyProperty(dbInfo);
            _unitWork.Updata(dbInfo);
            await _unitWork.CommitAsync();
        }

        /// <summary>
        /// 删除菜单
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException"></exception>
        public async Task DeleteAsync(Guid id)
        {
            var dbInfo = await _menuAuthorityRepository.FirstAsync(m => m.ID == id) ?? throw new InvalidOperationException("找不到此菜单权限");
            if (await _roleMenuRepository.CountAsync(m => m.MenuAuthorityID == id) > 0) throw new InvalidOperationException("有角色正在关联此菜单");
            _unitWork.Delete(dbInfo);
            await _unitWork.CommitAsync();
        }

        /// <summary>
        /// 获取
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="InvalidOperationException"></exception>
        public async Task<List<MenuAuthorityDTO>> GetAsync(List<Guid> id)
        {
            List<MenuView> dbInfo = await _menuAuthorityRepository.FindMenuView(m => id.Contains(m.ID)) ?? throw new InvalidOperationException("找不到此菜单权限");
            var result = _mapper.Map<List<MenuAuthorityDTO>>(dbInfo);
            return result;
        }

        /// <summary>
        /// 获取一级
        /// </summary>
        /// <param name="parentId"></param>
        /// <returns></returns>
        public async Task<List<MenuAuthorityListDTO>> GetOneLevelAsync(Guid? parentId)
        {
            List<MenuView> dbInfo = await _menuAuthorityRepository.FindMenuView(m => m.ParentID == parentId);
            var result = _mapper.Map<List<MenuAuthorityListDTO>>(dbInfo);
            return result;
        }

        /// <summary>
        /// 获取树
        /// </summary>
        /// <returns></returns>
        public async Task<List<MenuTreeDTO>> GetTreeAsync( Guid subsystemID)
        {
            List<MenuView> dbInfo = await _menuAuthorityRepository.FindMenuView(m => m.SubsystemID == subsystemID);
            var result = TreeConvert.EntityToTreeList<MenuTreeDTO, MenuView>(dbInfo);
            return result;
        }
    }

}